import numpy as np
from view.iNiceRunner import INiceRunner


class CalcComplexity:

    def __init__(self, d):
        assert d is not None
        self.D = d
        self.K = None
        self.E = None
        self.paiList = None

    def calcEntropy(self):
        assert self.paiList is not None, "run calcClusterNum first"
        self.E = 0
        for pai in self.paiList:
            self.E += pai*np.log2(pai)
        self.E = self.E * (-1)

    def calcClusterNum(self, sqlconn, name, dsId, observerGenClassName, nOb, clusterEstClassName, p2pClassName,
                       n2nClassName, filterCfgJSONDict, maxob, minob, mixedParamsCfgJSONDict=None):

        inR = INiceRunner()
        inR.setConfig(sqlConn=sqlconn, dsId=dsId, name=name, observerGenClassName=observerGenClassName,
                      nObservers=nOb, clusterEstimatorClassName=clusterEstClassName, one2oneClasName=p2pClassName,
                      n2nClassName=n2nClassName, filterCfgJSONDict=filterCfgJSONDict,
                      maxob=maxob, minob=minob, mixedParamsCfgJSONDict=mixedParamsCfgJSONDict)
        state, self.paiList = inR.run()
        assert 0 not in self.paiList
        assert isinstance(self.paiList, list)
        self.K = len(self.paiList)

    def calc(self):
        if self.K == 1:
            complexity = 0
            return complexity
        # complexity = 1 - (self.E / (np.log2((self.D + 1) * self.K) * np.log2(self.K)))
        complexity = 1 - (
                self.E /
                (np.log2(self.D + 1) * (np.log2(self.K))**2)
                          )
        return complexity
